package com.sea.utils;

import org.springframework.util.ObjectUtils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Calendar;
import java.util.Date;

public class ByteUtils {

    public static byte[] String(String o, int byteLen) {
        byte[] all = new byte[byteLen];
        byte[] bytes = o.getBytes();
        for (int i = 0; i < bytes.length; i++) {
            all[i] = bytes[i];
        }
        for (int i = bytes.length; i < 16; i++) {
            all[i] = 0;// 补0
        }
        return all;
    }

    public static String String(byte[] bytes) {
        if (null == bytes)
            return null;
        StringBuffer sb = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            sb.append(Character.forDigit((bytes[i] & 240) >> 4, 16));
            sb.append(Character.forDigit(bytes[i] & 15, 16));
        }
        // Hex 字符串
        String s = sb.toString();
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    public static byte[] Long(long o, int byteLength) {
        byte[] bytes = new byte[byteLength];
        for (int i = 0; i < byteLength; i++) {
            if (i == 0) {
                bytes[i] = (byte) o;
            } else {
                bytes[i] = (byte) (o >> i * 8);
            }
        }
        return bytes;
    }

    public static long Long(byte[] bytes) {
        if (bytes.length < 8) {
            byte[] _bytes = new byte[8];
            putZero(bytes, _bytes, false);
            bytes = _bytes;
        }
        ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, bytes.length);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        return buffer.getLong();
    }

    public static byte[] Date(Date aDate) {
        byte[] result = new byte[7];
        final Calendar aTime = Calendar.getInstance();
        aTime.setTime(aDate);
        final int milliseconds = aTime.get(Calendar.MILLISECOND);
        final int seconds = aTime.get(Calendar.SECOND);
        result[0] = (byte) (((seconds * 1000) + milliseconds) % 256);
        result[1] = (byte) (((seconds * 1000) + milliseconds) / 256);
        result[2] = (byte) aTime.get(Calendar.MINUTE);
        result[3] = (byte) aTime.get(Calendar.HOUR_OF_DAY);
        result[4] = (byte) aTime.get(Calendar.DAY_OF_MONTH);
        result[5] = (byte) (aTime.get(Calendar.MONTH) + 1);
        result[6] = (byte) (aTime.get(Calendar.YEAR) % 100);
        return result;
    }

    public static Date Date(byte[] bytes) {
        int milliseconds1 = bytes[0] < 0 ? 256 + bytes[0] : bytes[0];
        int milliseconds2 = bytes[1] < 0 ? 256 + bytes[1] : bytes[1];
        int milliseconds = (milliseconds1 + milliseconds2 * 256) % 1000;
        // 位于 0011 1111
        int minutes = bytes[2] & 0x3f;
        // 位于 0001 1111
        int hours = bytes[3] & 0x1f;
        // 位于 0000 1111
        int days = bytes[4] & 0x1f;
        // 位于 0001 1111
        int months = bytes[5] & 0x0f;
        // 位于 0111 1111
        int years = bytes[6] & 0x7f;
        final Calendar aTime = Calendar.getInstance();
        aTime.set(Calendar.MILLISECOND, milliseconds);
        aTime.set(Calendar.MINUTE, minutes);
        aTime.set(Calendar.HOUR_OF_DAY, hours);
        aTime.set(Calendar.DAY_OF_MONTH, days);
        aTime.set(Calendar.MONTH, months - 1);
        aTime.set(Calendar.YEAR, years + 2000);
        return aTime.getTime();
    }

    /**
     * BCD码转为10进制串(阿拉伯数据)
     *
     * @param bytes BCD码
     * @return 10进制串
     */
    public static Object BCD(byte[] bytes) {
		/*if (null == bytes || bytes.length == 0) {
			return 0;
		} else {
			// 存储转码后的字符串
			StringBuilder sb = new StringBuilder();

			// 循环数组解码
			for (int i = 0; i < bytes.length; i++) {
				// 转换低字节
				int low = (bytes[i] & 0x0f);
				sb.append(low);

				// 转换高字节
				int high = ((bytes[i] & 0xf0) >> 4);

				// 如果高字节等于0xf说明是补的字节，直接抛掉
				if (high != 0xf) {
					sb.append(high);
				}
			}
			// 返回解码字符串
			String str = sb.toString();
			return ObjectUtils.toLong(str);
		}*/

        StringBuffer temp = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        String value = temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1)
                : temp.toString();

        return value;
    }

    /**
     * 10进制串转为BCD码
     *
     * @param
     * @return BCD码
     */
    public static byte[] BCD(Object o, int len2) {
        String asc = o.toString();
        int len = asc.length();
        int mod = len % 2;
        if (mod != 0) {
            asc = "0" + asc;
            len = asc.length();
        }
        byte abt[] = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }
        byte bbt[] = new byte[len];
        abt = asc.getBytes();
        int j, k;
        for (int p = 0; p < asc.length() / 2; p++) {
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
                j = abt[2 * p] - '0';
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
                j = abt[2 * p] - 'a' + 0x0a;
            } else {
                j = abt[2 * p] - 'A' + 0x0a;
            }
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
                k = abt[2 * p + 1] - '0';
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
                k = abt[2 * p + 1] - 'a' + 0x0a;
            } else {
                k = abt[2 * p + 1] - 'A' + 0x0a;
            }
            int a = (j << 4) + k;
            byte b = (byte) a;
            bbt[p] = b;
        }

        byte[] by = bbt;
        byte[] bytes = new byte[len2];
        boolean highLow = true;

        if (by.length > bytes.length) {
            return by;
        }
        if (highLow) {
            int cont = bytes.length - by.length;
            for (int i = cont, l = 0; i < bytes.length; i++) {
                bytes[i] = by[l];
                l++;
            }
        } else {
            for (int i = 0; i < by.length; i++) {
                bytes[i] = by[i];
            }
        }
        return bytes;

    }

    public static String byteToHex(byte[] bytes) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        for (int i = 0; i < bytes.length; i++) {
            int v = bytes[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static byte[] hexToBytes(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    private static byte[] putZero(byte[] by, byte[] bytes, boolean highLow) {
        if (by.length > bytes.length) return by;
        if (highLow) {
            int cont = bytes.length - by.length;
            for (int i = cont, j = 0; i < bytes.length; i++) {
                bytes[i] = by[j];
                j++;
            }
        } else {
            for (int i = 0; i < by.length; i++) {
                bytes[i] = by[i];
            }
        }
        return bytes;
    }


//	public static void main(String[] args) {
//		String ss = "8813290e190815";
//		byte[] bytes = hexToBytes(ss);
//		long a = 1629873710000l;
//		Date aDate = new Date(a);
////		Date aDate = new Date();
//		System.out.println(aDate);
////		final byte[] bytes = Date(aDate);
//		for (byte aByte : bytes) {
//			System.out.print(aByte + " ");
//		}
//		System.out.println();
//		final Date date = Date(bytes);
//		System.out.println(date);
//	}
}
